require("auxlib");
-- dofile("C:\\Users\\Roger\\Dropbox\\_GAMEDEV\\NES\\nesadventure\\tests\\sandbox_v2\\src\\sandbox_v2.nes.lua")
dofile("labels.lua")

commandline = 
   iup.text{size="256x",value=""}

interpreter_pointer = 0

function write_interpreter( val ) 
      memory.writebyte( interpreter_pointer , math.floor( val % 256 ) )   
      memory.writebyte( interpreter_pointer+1, math.floor( val / 256 ) )   
      interpreter_pointer = interpreter_pointer + 2
end

function explode(d,p)  -- separator, string
  local t, ll
  t={}
  ll=0
  if(#p == 1) then return {p} end
    while true do
      l=string.find(p,d,ll,true) -- find the next d in the string
      if l~=nil then -- if found
        s = string.sub(p,ll,l-1)
        if string.len( s ) > 0 then
           table.insert(t, s) -- Save it in our array.
        end
        ll=l+1 -- save just after where we found it for searching next time.
      else
        s = string.sub(p,ll)
        if string.len( s ) > 0 then
          table.insert(t, s) -- Save what's left in our array.
        end
        break
      end
    end
  return t
end


function vardump(value, depth, key)
  local linePrefix = ""
  local spaces = ""
  
  if key ~= nil then
    linePrefix = "["..key.."] = "
  end
  
  if depth == nil then
    depth = 0
  else
    depth = depth + 1
    for i=1, depth do spaces = spaces .. "  " end
  end
  
  if type(value) == 'table' then
    mTable = getmetatable(value)
    if mTable == nil then
      print(spaces ..linePrefix.."(table) ")
    else
      print(spaces .."(metatable) ")
        value = mTable
    end     
    for tableKey, tableValue in pairs(value) do
      vardump(tableValue, depth, tableKey)
    end
  elseif type(value) == 'function' or 
      type(value) == 'thread' or 
      type(value) == 'userdata' or
      value    == nil
  then
    print(spaces..tostring(value))
  else
    print(spaces..linePrefix.."("..type(value)..") "..tostring(value))
  end
end

function interpret( str )
   interpreter_pointer = labels["INTERPRETER_BUF"]["value"]
   words = explode(" ",str)
   vardump( words )   
   for key,word in pairs(words) do
      if tonumber(word) ~= nil then
         if math.abs(tonumber(word)) < 256 then
            write_interpreter( labels["lit"]["value"] )
         else
            write_interpreter( labels["twolit"]["value"] )
         end
         write_interpreter( tonumber(word) )    
      else
         write_interpreter( labels[word]["value"] )
      end
   end

   write_interpreter( labels["end_interpreter"]["value"] )
end

update_flag = 0

function commandline:k_any (c)
   if c == iup.K_CR then
      output.append = "\n"..commandline["value"];
      interpret( commandline["value"] )
      commandline["value"] = ""   
      update_flag = 2
   end
   return iup.CONTINUE
end

output =   
   iup.multiline{size="256x120",
         expand="YES",
         value="",
         appendnewline="NO"
      }

stack =
   iup.label{ title="                                                                                                 " }

function update_stack ()
   numitems = 0xbf - memory.readbyte( labels["INTERPRETER_SP"]["value"]  )
   stack.title = numitems..": ";
   for i=0,numitems-1 do
      stack.title  = stack.title .. string.format( "%02X", memory.readbyte( 0x1c2 - i ) ) .. " "
      stack.width = 256;
   end
end

btn = iup.button{title="Clear Stack"}

function btn:action() 
   memory.writebyte( labels["INTERPRETER_SP"]["value"], 0xbf )
   update_flag = 2
   return iup.DEFAULT
end

dialogs = dialogs + 1; -- there is no ++ in Lua
handles[dialogs] = iup.dialog{
   title="Eighth Console",
   iup.vbox{
      btn,
      commandline,
      output,
      stack,
      gap="5",
      alignment="ALEFT",
      margin="5x5"      
   },
   
};

handles[dialogs]:show(); -- this actually shows you the dialog. Note that this is equivalent to calling handles[dialogs].show(handles[dialogs]); just shorter.

-- memory.writebyte( labels["INTERPRETER_SP"]["value"], 0xbf )

update_flag = 5

iup.SetFocus( commandline )

while (true) do
   FCEU.frameadvance()
   if ( update_flag > 0 ) then
      update_stack()
      update_flag = update_flag - 1
   end
end;